package modelo;

import java.util.Observable;
import java.util.Observer;

/**
 * Todas las magnitudes se guardan en el sistema MKS 
 * a menos que se indique lo contrario.
 * A saber: [a] = m/s2, [v] = m/s, [x] = m, [t] = s 
 */

/**
 * el motor observa el Cronometro
 */
public abstract class Motor extends Observable implements Observer{
	protected double aceleracion;
	protected double velocidad;
	protected double velocidadMaxima; // se define desde cada tipo de motor
	protected long TIEMPO_DE_ACTUALIZACION__mS = Cronometro.INTERVALO_DE_TIEMPO;

	public abstract double obtenerAceleracionMax();

	public Motor(){
		this.aceleracion = 0;
		this.velocidad= 0;
		Cronometro.getInstance().addObserver(this);
	}
	
	public void update(Observable o, Object args){
		validarAceleracion();
		/* formula: velocidadFinal = velocidadInicial + aceleracion * tiempo */
		/* se asigna el minimo con la VelocidadMaxima para que la velocidad nunca 
		 * supere la maxima */ 
		velocidad = Math.min(velocidad + aceleracion
				* Convertir.mX_a_X(TIEMPO_DE_ACTUALIZACION__mS), velocidadMaxima);
		if (velocidad == velocidadMaxima)
			aceleracion = 0;
		
		/* en el caso de que venga frenando, para que no quede con 
		 * velocidad negativa */
		if ( velocidad <= 0 ){ 
			velocidad = 0;     
			aceleracion = 0;
		}
		notificarObservadores();
	}

	protected void validarAceleracion() {
		if (this.getVelocidad() == this.getVelocidadMax())
			aceleracion = 0;
	}

	public void acelerar(){
		if(velocidad == velocidadMaxima) return;
		aceleracion = this.obtenerAceleracionMax();
		notificarObservadores();
	}

	public void aceleracionCte(){
		this.aceleracion = 0;
		notificarObservadores();
	}
	 
	public void frenar(){
		if (velocidad == 0) return;
		aceleracion = (-1)*this.obtenerAceleracionMax();
		notificarObservadores();
	}
	
	public double getAceleracion() {
		return aceleracion;
	}
	
	public double getVelocidadMax() {
		return velocidadMaxima;
	}
	
	public double getVelocidad() {
		return velocidad;
	}
	
    public void notificarObservadores(){
    	setChanged();
    	notifyObservers();
    }
    
    public void reiniciar(){
		this.aceleracion = 0;
		this.velocidad= 0;
    }
}